<html>
<head><meta charset="utf-8"><title>swizzle/shuffle APIs · project-portable-simd · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/index.html">project-portable-simd</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html">swizzle/shuffle APIs</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="212378542"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212378542" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212378542">(Oct 06 2020 at 02:31)</a>:</h4>
<p><span class="user-mention" data-user-id="209168">@Thom Chiovoloni</span> asked about these as well.<br>
Currently: <a href="https://github.com/rust-lang/stdsimd/issues/11">https://github.com/rust-lang/stdsimd/issues/11</a><br>
There was some discussion of using a macro-based form "in the meanwhile" for shuffles, a long time ago in a thread far far away, but everyone pretty quickly came to the conclusion that const generics would become strong enough fast enough to reasonably enable just using a single const generic shuffle API, so we don't have to double-up on the potential calls like that.</p>



<a name="212380630"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212380630" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212380630">(Oct 06 2020 at 03:18)</a>:</h4>
<p>specifically, min_const_generics is aimed at "by the end of the year" as a stabilization goal.</p>



<a name="212380736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212380736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212380736">(Oct 06 2020 at 03:20)</a>:</h4>
<p>so, one complexity is that you need one source lane for each output lane, and for 4 or maybe 8 lanes that's not bad, but it gets silly fast.</p>



<a name="212380833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212380833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212380833">(Oct 06 2020 at 03:22)</a>:</h4>
<p>that is, to shuffle f32x4 or i32x4 you pass in [usize;4] as the const generic, and then if you have u8x16 you'd pass [usize;16], which would be borderline unreadable.</p>



<a name="212380864"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212380864" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212380864">(Oct 06 2020 at 03:23)</a>:</h4>
<p>of course in x64 there are also runtime shuffles, so i suspect we should allow those as well</p>



<a name="212382906"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212382906" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212382906">(Oct 06 2020 at 04:08)</a>:</h4>
<p>What are the perf implications of those?<br>
There was an argument against implementing Index due to naive usage of (dynamic?) insert/extract being a perf footgun, and I know that shuffles can be significantly more Fun in those terms.</p>



<a name="212383265"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212383265" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212383265">(Oct 06 2020 at 04:17)</a>:</h4>
<p>Would things like interleaving just use specific const shuffles?</p>



<a name="212383533"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212383533" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212383533">(Oct 06 2020 at 04:23)</a>:</h4>
<p>hm.</p>



<a name="212383682"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212383682" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212383682">(Oct 06 2020 at 04:27)</a>:</h4>
<p>I am pretty sure some architectures are going to do much better on some interleaving ops? We can't capture every vendor API's nuances, but I think when things typically have very different performance implications, we should seriously consider exposing multiple different functions.</p>



<a name="212383794"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212383794" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212383794">(Oct 06 2020 at 04:29)</a>:</h4>
<p>unless you mean on our side. Probably?<br>
( also making people write every lane in a common pattern on those 512-bit lane ops seems cruel. )</p>



<a name="212384304"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384304" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384304">(Oct 06 2020 at 04:41)</a>:</h4>
<p>on x64 the dynamic shuffles consume a register to provide the dynamic values, instead of having the shuffle pattern be encoded as an immediate within the instruction</p>



<a name="212384349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384349">(Oct 06 2020 at 04:42)</a>:</h4>
<p>so there can be register pressure perhaps</p>



<a name="212384443"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384443" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384443">(Oct 06 2020 at 04:44)</a>:</h4>
<p>the problem with Index being insert/extract is that Index and IndexMut generate references, and having references is what can be the problem. A reference has to point to a real place, so if llvm can't fully eliminate it then the value has to go out of register onto the stack</p>



<a name="212384476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384476">(Oct 06 2020 at 04:45)</a>:</h4>
<p>oof.</p>



<a name="212384530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384530">(Oct 06 2020 at 04:46)</a>:</h4>
<p>oh i worded that wrong a bit.</p>
<ul>
<li>extract: fn(vec, index)-&gt;elem</li>
<li>index: fn(&amp;vec, index)-&gt;*(&amp;elem)</li>
</ul>



<a name="212384549"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384549" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384549">(Oct 06 2020 at 04:46)</a>:</h4>
<p>that hopefully makes it clearer maybe. the self type of index doesn't match the self type of extract, index has to be more general, which for us is worse</p>



<a name="212384680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384680">(Oct 06 2020 at 04:50)</a>:</h4>
<p>right.</p>



<a name="212384726"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384726" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384726">(Oct 06 2020 at 04:50)</a>:</h4>
<p>actually, x64 has quite limited lane movement options, to the point where it can quickly cause problems. I think neon has similar problems.</p>
<p>we might be better served with making it easy to use, and people can try to use <code>arch</code> and conditional compilation if they think they can do better.</p>



<a name="212384825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212384825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212384825">(Oct 06 2020 at 04:52)</a>:</h4>
<p>This is one area where I'm extra comfortable just telling LLVM the intent as clearly as possible and trusting to ferris</p>



<a name="212385014"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385014" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385014">(Oct 06 2020 at 04:57)</a>:</h4>
<p>neon has vget, vset, etc.</p>



<a name="212385073"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385073" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385073">(Oct 06 2020 at 04:58)</a>:</h4>
<p><a href="https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/coding-for-neon---part-5-rearranging-vectors">https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/coding-for-neon---part-5-rearranging-vectors</a> and these</p>



<a name="212385274"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385274" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385274">(Oct 06 2020 at 05:02)</a>:</h4>
<p>vtbl and vtbx are uh... powerful.</p>



<a name="212385440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385440">(Oct 06 2020 at 05:07)</a>:</h4>
<p>as always, neon does what inteldon't</p>



<a name="212385589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385589">(Oct 06 2020 at 05:10)</a>:</h4>
<p>There's a reason I basically have unashamedly said "yeah Neon makes more sense generally."<br>
hrm.<br>
so the problem with extract is that it takes by value, but index has to be a reference. However, I am not sure... in our case wouldn't that almost always be optimized away? Ugh, I guess I'm asking a bit much of Ferris on that "almost always" there.</p>



<a name="212385664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385664">(Oct 06 2020 at 05:12)</a>:</h4>
<p>but we're talking about simple values here.</p>



<a name="212385820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212385820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212385820">(Oct 06 2020 at 05:16)</a>:</h4>
<p>and there's no IndexMove trait, ofc.</p>



<a name="212386078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212386078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212386078">(Oct 06 2020 at 05:22)</a>:</h4>
<p>If you're trying to be clever, I would actually like to be able to conditionally compile different shuffles (but still using std::simd) to be able to take advantage of different architectures shuffle semantics while still being able to get the benefits of portable SIMD (mostly respecting target_feature)</p>



<a name="212386098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212386098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212386098">(Oct 06 2020 at 05:23)</a>:</h4>
<p>So I would hope the shuffle API is flexible enough for that</p>



<a name="212387176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212387176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212387176">(Oct 06 2020 at 05:48)</a>:</h4>
<p>i think we should simply <em>always</em> provide immediate shuffle and varying shuffle, and the benefits of immediate shuffle are just sometimes less on a given instruction set.</p>



<a name="212387291"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212387291" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212387291">(Oct 06 2020 at 05:51)</a>:</h4>
<p>True, I suppose immediate shuffle should never be worse than varying</p>



<a name="212388890"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/swizzle/shuffle%20APIs/near/212388890" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/swizzle.2Fshuffle.20APIs.html#212388890">(Oct 06 2020 at 06:24)</a>:</h4>
<p>That seems reasonable. There are algorithms that specifically need to use shuffle with runtime selection of components (those that use registers as lookup tables, for instance). And then there are algorithms that use a fixed-shuffle with a constant defined at compile time. Supplying mechanisms for both and compiling both to the best code we can on each platform makes sense.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>